/**********************************************************************
*  Copyright (c) 2007 - Victor Jacobs - victor.jacobs@gmail.com
*
*  Permission is hereby granted, free of charge, to any person
*  obtaining a copy of this software and associated documentation
*  files (the "Software"), to deal in the Software without
*  restriction, including without limitation the rights to use,
*  copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the
*  Software is furnished to do so, subject to the following
*  conditions:
*
*  The above copyright notice and this permission notice shall be
*  included in all copies or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*  OTHER DEALINGS IN THE SOFTWARE.
**********************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Vj.GraphLibrary;
using Vj.MathLibrary;

namespace Vj.GraphApp
{
    public partial class GraphControl : UserControl
    {
        private Graphics myGraphic;
        private Graph graph;

        public Graph Graph
        {
            get { return graph; }
            set { graph = value; }
        }

        private Color nodeColor;

        public Color NodeColor
        {
            get { return nodeColor; }
            set { nodeColor = value; }
        }

        private Color linkColor;

        public Color LinkColor
        {
            get { return linkColor; }
            set { linkColor = value; }
        }
        
        public GraphControl()
        {
            InitializeComponent();
            
            this.nodeColor = Color.DarkBlue;
            this.linkColor = Color.LightBlue;
        }

        public GraphControl(Color nodeColor, Color linkColor)
        {
            InitializeComponent();

            this.nodeColor = nodeColor;
            this.linkColor = linkColor;
        }

        public void DrawGraph(Graphics g)
        {
            int xOffset = this.Width/2;
            int yOffset = this.Height/2;

            #region Draw the nodes

            Random rg = new Random();
            float sizeOfNode = 20.0f;

            //draw nodes
            for (int i = 0; i < graph.Nodes.Count; i++)
            {
                Vector center = graph.Nodes[i].Location;
                g.DrawEllipse(new Pen(nodeColor),
                    (float)center.X - sizeOfNode / 2.0f + xOffset, (float)center.Y - sizeOfNode / 2.0f + yOffset, sizeOfNode, sizeOfNode);
            }

            #endregion

            #region Draw connections

            // draw connections
            for (int i = 0; i < graph.Nodes.Count; i++)
            {
                for (int j = 0; j < graph.Nodes[i].Connections.Count; j++)
                {
                    Vector pt1 = graph.Nodes[i].Location;
                    Vector pt2 = graph.Nodes[i].Connections[j].EndNode.Location;
                    g.DrawLine(new Pen(linkColor), (float)pt1.X + xOffset, (float)pt1.Y + yOffset, 
                                                   (float)pt2.X + xOffset, (float)pt2.Y + yOffset);
                }
            }

            #endregion
        }

        private void DrawValues()
        {
            int xOffset = this.Width / 2;
            int yOffset = this.Height / 2;


            if (Controls.Count > 5)
               // Controls.Clear();
            
            for (int i = 0; i < graph.Nodes.Count; i++)
            {
                Label tmpLabel = new Label();

                Vector center = graph.Nodes[i].Location;
                center.X -= 6;
                center.Y -= 6;

                tmpLabel.Location = new Point((int)center.X + xOffset, (int)center.Y + yOffset);
                //tmpLabel.BackColor = Color.Transparent;
                tmpLabel.ForeColor = this.ForeColor;
                tmpLabel.Size = new Size(15, 13);
                tmpLabel.Text = i.ToString();

                this.Controls.Add(tmpLabel);
            }
        }

        private void GraphControl_Paint(object sender, PaintEventArgs e)
        {
            Bitmap drawing = null;
            drawing = new Bitmap(this.Width, this.Height, e.Graphics);
            myGraphic = Graphics.FromImage(drawing);

            if (graph != null)
            {
                DrawGraph(myGraphic);
                DrawValues();
            }

            e.Graphics.DrawImageUnscaled(drawing, 0, 0);
            myGraphic.Dispose();
        }
    }
}
